package com.daydreamdev.secondskill.middle.rabbit;

import com.daydreamdev.secondskill.middle.rabbit2.RabbitConfig;
import com.daydreamdev.secondskill.service.api.StockService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Component
@Slf4j
public class CanalDelCacheReceiver { //消费者
    int count = 1;

    @Autowired
    private StockService stockService;

    //注意： 重试并不是 RabbitMQ 重新发送了消息到了队列，仅仅是消费者内部进行了重试，换句话说就是重试跟mq没有任何关系。
    // 上述消费者代码不能添加try{}catch(){}，一旦捕获了异常，在自动 ack 模式下，就相当于消息正确处理了，消息直接被确认掉了，
    // 不会触发重试的。 当然并不是说不能添加 try{}catch(){}，而是不能将异常给处理了。可以如下写：
    @RabbitListener(queues = RabbitMqConfig.canalDelCacheQueue, containerFactory = "testFactory1")
    public void infoConsumption(Message message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws Exception {
        log.info("重试次数 = {}", count++);
        String sid = new String(message.getBody(), "UTF-8");
        try {
            // 删除库存缓存
            // int i = 10 / 0;
            stockService.delStockCountCache(Integer.parseInt(sid));
            // 处理主要业务
            // int i = 10 / 0;
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {

            // //消息退回 (可以在可视化界面看到)
            // //批量退回 退回之后重回消息队列 true  false的话就是丢弃这条信息，如果配置了死信队列，那这条消息会进入死信队列
            //channel.basicNack(deliveryTag, false, true); //这个是给死信机制用的，重试机制不要加否则会死循环(重试机制已经有最少1次最多5次的配置(走入catch消息会自动返回到重试队列'canal_del_cache_queue')，完全用不着这条代码！)
            // //单条退回 channel.basicReject();

            // 处理业务失败，还要进行其他操作，比如记录失败原因
            log.info("记录失败原因 ====>" + e.getMessage());
            log.info("记录失败原因 ====>" + e.getMessage());
            // throw new RuntimeException("手动抛出" + e.getMessage());//抛出异常后‘canal_del_cache_queue’就不会在处理了！

        }
    }

    // //测试重试
    // @RabbitListener(queues = "${mq.queueBinding.queue}")
    // public void infoConsumption(String data, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception {
    //     log.info("重试次数 = {}", count++);
    //     int i = 10 / 0;
    //     channel.basicAck(tag, false);
    // }
}